import { Request, Response, NextFunction } from 'express';
import { IUser } from '@database/models/User';
import PermissionChecker from '@utils/permissions';
import logger from '@utils/logger';

/**
 * 扩展 Express Request 类型，添加组织和团队信息
 */
declare global {
  namespace Express {
    interface Request {
      organizationId?: string;
      teamId?: string;
    }
  }
}

/**
 * 权限检查中间件
 * 要求用户必须有指定的权限才能访问
 */
export const requirePermission = (permissionName: string, scope: 'global' | 'organization' | 'team' = 'organization'): ((req: Request, res: Response, next: NextFunction) => Promise<void>) => {
  return async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      // 检查用户是否已认证
      if (!req.user) {
        res.status(401).json({
          success: false,
          message: 'Authentication required'
        });
        return;
      }

      let hasPermission = false;

      switch (scope) {
        case 'global':
          // 检查全局权限
          hasPermission = await PermissionChecker.hasGlobalPermission(req.user!, permissionName);
          break;

        case 'organization':
          // 检查组织权限
          const orgId = req.organizationId || req.params.organizationId || req.body.organizationId;
          if (!orgId) {
            res.status(400).json({
              success: false,
              message: 'Organization ID is required'
            });
            return;
          }
          hasPermission = await PermissionChecker.hasOrganizationPermission(req.user!, orgId, permissionName);
          break;

        case 'team':
          // 检查团队权限
          const teamId = req.teamId || req.params.teamId || req.body.teamId;
          if (!teamId) {
            res.status(400).json({
              success: false,
              message: 'Team ID is required'
            });
            return;
          }
          hasPermission = await PermissionChecker.hasTeamPermission(req.user!, teamId, permissionName);
          break;
      }

      if (!hasPermission) {
        logger.warn(`User ${req.user!._id} attempted to access ${permissionName} without permission`);
        res.status(403).json({
          success: false,
          message: 'Permission denied'
        });
        return;
      }

      next();
    } catch (error) {
      logger.error('Permission check error:', error as Error);
      res.status(500).json({
        success: false,
        message: 'Permission check failed'
      });
      return;
    }
  };
};

/**
 * 检查用户是否拥有任一权限
 */
export const requireAnyPermission = (permissionNames: string[], scope: 'organization' | 'team' = 'organization'): ((req: Request, res: Response, next: NextFunction) => Promise<void>) => {
  return async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      if (!req.user) {
        res.status(401).json({
          success: false,
          message: 'Authentication required'
        });
        return;
      }

      const orgId = req.organizationId || req.params.organizationId || req.body.organizationId;
      if (!orgId && scope === 'organization') {
        res.status(400).json({
          success: false,
          message: 'Organization ID is required'
        });
        return;
      }

      const hasPermission = await PermissionChecker.hasAnyPermission(req.user!, orgId, permissionNames);

      if (!hasPermission) {
        res.status(403).json({
          success: false,
          message: 'Permission denied'
        });
        return;
      }

      next();
    } catch (error) {
      logger.error('Permission check error:', error as Error);
      res.status(500).json({
        success: false,
        message: 'Permission check failed'
      });
      return;
    }
  };
};

/**
 * 检查用户是否拥有所有权限
 */
export const requireAllPermissions = (permissionNames: string[], scope: 'organization' | 'team' = 'organization'): ((req: Request, res: Response, next: NextFunction) => Promise<void>) => {
  return async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      if (!req.user) {
        res.status(401).json({
          success: false,
          message: 'Authentication required'
        });
        return;
      }

      const orgId = req.organizationId || req.params.organizationId || req.body.organizationId;
      if (!orgId && scope === 'organization') {
        res.status(400).json({
          success: false,
          message: 'Organization ID is required'
        });
        return;
      }

      const hasPermission = await PermissionChecker.hasAllPermissions(req.user!, orgId, permissionNames);

      if (!hasPermission) {
        res.status(403).json({
          success: false,
          message: 'Permission denied'
        });
        return;
      }

      next();
    } catch (error) {
      logger.error('Permission check error:', error as Error);
      res.status(500).json({
        success: false,
        message: 'Permission check failed'
      });
      return;
    }
  };
};

/**
 * 检查用户是否是组织管理员
 */
export const requireOrganizationAdmin = async (req: Request, res: Response, next: NextFunction) => {
  try {
    if (!req.user) {
      res.status(401).json({
        success: false,
        message: 'Authentication required'
      });
      return;
    }

    const orgId = req.organizationId || req.params.organizationId || req.body.organizationId;
    if (!orgId) {
      res.status(400).json({
        success: false,
        message: 'Organization ID is required'
      });
      return;
    }

    const isAdmin = await PermissionChecker.isOrganizationAdmin(req.user!, orgId);
    if (!isAdmin) {
      res.status(403).json({
        success: false,
        message: 'Organization admin access required'
      });
      return;
    }

    next();
  } catch (error) {
    logger.error('Admin check error:', error as Error);
    res.status(500).json({
      success: false,
      message: 'Admin check failed'
    });
    return;
  }
};

/**
 * 检查用户是否是组织所有者
 */
export const requireOrganizationOwner = async (req: Request, res: Response, next: NextFunction) => {
  try {
    if (!req.user) {
      res.status(401).json({
        success: false,
        message: 'Authentication required'
      });
      return;
    }

    const orgId = req.organizationId || req.params.organizationId || req.body.organizationId;
    if (!orgId) {
      res.status(400).json({
        success: false,
        message: 'Organization ID is required'
      });
      return;
    }

    const isOwner = await PermissionChecker.isOrganizationOwner(req.user!, orgId);
    if (!isOwner) {
      res.status(403).json({
        success: false,
        message: 'Organization owner access required'
      });
      return;
    }

    next();
  } catch (error) {
    logger.error('Owner check error:', error as Error);
    res.status(500).json({
      success: false,
      message: 'Owner check failed'
    });
    return;
  }
};

/**
 * 检查用户是否是团队负责人
 */
export const requireTeamLeader = async (req: Request, res: Response, next: NextFunction) => {
  try {
    if (!req.user) {
      res.status(401).json({
        success: false,
        message: 'Authentication required'
      });
      return;
    }

    const teamId = req.teamId || req.params.teamId || req.body.teamId;
    if (!teamId) {
      res.status(400).json({
        success: false,
        message: 'Team ID is required'
      });
      return;
    }

    const isLeader = await PermissionChecker.isTeamLeader(req.user!, teamId);
    if (!isLeader) {
      res.status(403).json({
        success: false,
        message: 'Team leader access required'
      });
      return;
    }

    next();
  } catch (error) {
    logger.error('Team leader check error:', error as Error);
    res.status(500).json({
      success: false,
      message: 'Team leader check failed'
    });
    return;
  }
};

/**
 * 检查用户是否是组织成员
 */
export const requireOrganizationMember = async (req: Request, res: Response, next: NextFunction) => {
  try {
    if (!req.user) {
      res.status(401).json({
        success: false,
        message: 'Authentication required'
      });
      return;
    }

    const orgId = req.organizationId || req.params.organizationId || req.body.organizationId;
    if (!orgId) {
      res.status(400).json({
        success: false,
        message: 'Organization ID is required'
      });
      return;
    }

    const isMember = req.user!.isMemberOfOrganization(orgId);
    if (!isMember) {
      res.status(403).json({
        success: false,
        message: 'Organization membership required'
      });
      return;
    }

    // 将组织 ID 附加到请求对象
    req.organizationId = orgId;
    next();
  } catch (error) {
    logger.error('Membership check error:', error as Error);
    res.status(500).json({
      success: false,
      message: 'Membership check failed'
    });
    return;
  }
};

/**
 * 权限检查装饰器工厂
 * 用于快速创建资源特定的权限检查中间件
 */
export const createResourcePermissionMiddleware = (resource: string) => {
  return {
    read: requirePermission(`${resource}:read`),
    create: requirePermission(`${resource}:create`),
    update: requirePermission(`${resource}:update`),
    delete: requirePermission(`${resource}:delete`),
    manage: requirePermission(`${resource}:manage`)
  };
};

// 导出常用资源的权限中间件
export const alertsPermission = createResourcePermissionMiddleware('alerts');
export const ticketsPermission = createResourcePermissionMiddleware('tickets');
export const knowledgePermission = createResourcePermissionMiddleware('knowledge');
export const organizationsPermission = createResourcePermissionMiddleware('organizations');
export const teamsPermission = createResourcePermissionMiddleware('teams');
export const usersPermission = createResourcePermissionMiddleware('users');
export const rolesPermission = createResourcePermissionMiddleware('roles');
